/**
 * Copyright (C) 2010 Cloudfarming <info@cloudfarming.nl>
 *
 * Licensed under the Eclipse Public License - v 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nl.cloudfarming.client.planning.tactical;

import java.awt.BorderLayout;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
import org.jdesktop.swingx.JXPanel;
import org.netbeans.validation.api.Problems;
import org.netbeans.validation.api.builtin.Validators;
import org.netbeans.validation.api.ui.ValidationListener;
import org.netbeans.validation.api.ui.ValidationPanel;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;

/**
 * Controller which provides panel for creating a FieldPlan. The panel is validated on the following properties:
 * FieldPlan.year : number 4 characters long
 * FieldPlan.name : mandatory
 * @author Merijn Zengers
 */
public class FieldPlanController extends ValidationListener implements KeyListener {

    private FieldPlanPanel panel;

    public FieldPlanController() {
        panel = new FieldPlanPanel();
    }

    /**
     * init the panel
     */
    public final void initPanel() {
        panel.addValidationListener(this);
        panel.getFieldPlanName().addKeyListener(this);
        panel.getFieldPlanYear().addKeyListener(this);
        panel.setVisible();
    }

    /**
     * Checks if there are any Problems. if so disable OK button
     * @param prblms
     * @return alwayas true
     */
    @Override
    protected final boolean validate(Problems prblms) {
        if (prblms.hasFatal()) {
            panel.setValid(false);
        } else {
            panel.setValid(true);
        }
        return true;
    }

    /**
     * Not used
     * @param e 
     */
    @Override
    public void keyTyped(KeyEvent e) {
    }

    /**
     * Not used
     * @param e 
     */
    @Override
    public void keyPressed(KeyEvent e) {
    }

    /**
     * Triggers validateAll on the ValidationGroup of the panel
     * @param e 
     */
    @Override
    public final void keyReleased(KeyEvent e) {
        panel.validateAll();
    }
}

/**
 * Panel for a new FieldPlan
 * @author Merijn Zengers
 */
class FieldPlanPanel extends JXPanel {

    private SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
    private Dialog dlg;
    private JTextField fieldPlanYear;
    private JTextField fieldPlanName;
    private JButton jButtonOK;
    private TacticalPlanningService service;
    private ValidationPanel validationPanel;
   
    private static final int FIELDPLAN_NAME_LENGHT = 160;
    private static final int FIELDPLAN_YEAR_LENGHT = 40;
    private static final String GAP_LEFT = "gapleft 15";
    private static final String GAP_RIGHT = "gapright 15";
    private final String DISPLAY_NAME = NbBundle.getMessage(this.getClass(), "field_plan.new_field_plan_action.action_name");
    private final String FIELD_PLAN_NAME_LABEL = NbBundle.getMessage(this.getClass(), "field_plan.new_field_plan_action.name");
    private final String FIELD_PLAN_YEAR_LABEL = NbBundle.getMessage(this.getClass(), "field_plan.new_field_plan_action.year");
    private final int FIELD_PLAN_YEAR_LENGHT = 4;
    private final String OK_BUTTON_TEXT = NbBundle.getMessage(this.getClass(), "field_plan.new_field_plan_action.ok");
    private final String CANCEL_BUTTON_TEXT = NbBundle.getMessage(this.getClass(), "field_plan.new_field_plan_action.cancel");
    private final String YEAR = NbBundle.getMessage(this.getClass(), "field_plan.new_field_plan_action.fieldplan_name", yearFormat.format(new Date()) + "");

    public FieldPlanPanel() {
        JXPanel componentPanel;
        //
        // populate the panel with the information about what the user is about to save
        //
        this.setLayout(new BorderLayout());
        componentPanel = new JXPanel(new MigLayout("wrap 2"));
        validationPanel = new ValidationPanel();
        fieldPlanName = new JTextField(YEAR);
        fieldPlanName.setPreferredSize(new Dimension(FIELDPLAN_NAME_LENGHT, 0));
        fieldPlanYear = new JTextField(yearFormat.format(new Date()));
        fieldPlanYear.setPreferredSize(new Dimension(FIELDPLAN_YEAR_LENGHT, 0));

        //fieldName is mandatory
        validationPanel.getValidationGroup().add(this.fieldPlanName, Validators.REQUIRE_NON_EMPTY_STRING);

        //fieldYear should be a number and four positions long
        validationPanel.getValidationGroup().add(this.fieldPlanYear, Validators.validNumber(Locale.getDefault()), Validators.minLength(FIELD_PLAN_YEAR_LENGHT), Validators.maxLength(FIELD_PLAN_YEAR_LENGHT));

        componentPanel.add(new JLabel(FIELD_PLAN_NAME_LABEL), GAP_LEFT);
        
        StringBuilder propBuilder = new StringBuilder(GAP_LEFT);
        propBuilder.append(",");
        propBuilder.append(GAP_RIGHT);
        
        componentPanel.add(fieldPlanName, propBuilder.toString());

        componentPanel.add(new JLabel(FIELD_PLAN_YEAR_LABEL), GAP_LEFT);

        
        componentPanel.add(fieldPlanYear, GAP_LEFT);

        //Validation    
        validationPanel.setInnerComponent(componentPanel);
        this.add(validationPanel);


        //
        // create the dialog and add the ok and cancel buttons
        //
        DialogDescriptor dd = new DialogDescriptor(this, DISPLAY_NAME);
        dd.setOptions(new Object[]{getOkButton(), getCancelButton()});
        dlg = DialogDisplayer.getDefault().createDialog(dd);
    }

    public void setVisible() {
        dlg.setVisible(true);
    }
    
    /**
     * Get the textField containing the FieldPlan name
     * @return JTextField fieldPlanName
     */
    public JTextField getFieldPlanName() {
        return fieldPlanName;
    }

    /**
     * Get the textField containing the FieldPlan year
     * @return JtextField fieldPlanName
     */
    public JTextField getFieldPlanYear() {
        return fieldPlanYear;
    }

    /**
     * Sets the forms status. wil enable or disable the OK button on the dialog
     * @param valid boolean valid
     */
    public void setValid(boolean valid){
        getOkButton().setEnabled(valid);
    }
    
    /**
     * creates the dialog ok button
     *
     * @return
     */
    private JButton getOkButton() {
        if (jButtonOK == null) {
            jButtonOK = new JButton();
            jButtonOK.setText(OK_BUTTON_TEXT);
            jButtonOK.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent ae) {
                    dlg.setVisible(false);
                    String yearText = fieldPlanYear.getText();
                    int year = Integer.parseInt(yearText);
                    String nameText = fieldPlanName.getText();
                    getService().createFieldPlanForYear(nameText, year);
                }
            });
        }
        return jButtonOK;
    }

    /**
     * creates the dialog cancel button
     * @return
     */
    private JButton getCancelButton() {
        JButton jButtonCancel = new JButton();
        jButtonCancel.setText(CANCEL_BUTTON_TEXT);
        jButtonCancel.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                dlg.setVisible(false);
            }
        });
        return jButtonCancel;
    }

    /**
     * Adds a validationListener to this panels ValidationGroup
     * @param validationListener 
     */
    public void addValidationListener(ValidationListener validationListener) {
        if (validationPanel != null) {
            validationPanel.getValidationGroup().add(validationListener);
        }
    }

    /**
     * invokes the validateAll method on the ValidationGroup
     */
    public void validateAll() {
        validationPanel.getValidationGroup().validateAll();
    }

    protected TacticalPlanningService getService() {
        if (service == null) {
            service = Lookup.getDefault().lookup(TacticalPlanningService.class);
        }
        return service;
    }
}
